package middlewareWeb;
import java.net.*;
import java.io.*;
/**
 *
 * @author myusy
 */
public class ManagerThreadPop implements Runnable{
    protected DatagramSocket socketPop;
    protected ObjectInputStream ois;
    protected ObjectOutputStream oos;
    protected DatagramPacket packetIn;
    protected byte[] buffer;

    /**
     * Metodo costruttore della classe Manager ThreadPop
     */
    public ManagerThreadPop(DatagramPacket packetIn){
        this.packetIn = packetIn;
    }
    
    /**
     * Metodo che esegue il pop
     */
    public void run() {
        try
        {
                socketPop = new DatagramSocket();
                System.out.println("Avvio un thread manager pop");
                ByteArrayInputStream bin = new ByteArrayInputStream(packetIn.getData());
                System.out.println("ricevo link da "+ packetIn.getAddress() + " " + packetIn.getPort());
                ObjectInputStream oin = new ObjectInputStream(bin);

                String LinkRead = (String)oin.readObject();
    
                System.out.println("Ho ricevuto dal Worker: "+LinkRead);
                oin.close();

                FileInputStream fis = new FileInputStream(LinkRead);

                int cnt;
                int i = 1;
                System.out.println("Mi preparo a trasmettere");
                
                byte[] fileBuffer = new byte[512];
                while ((cnt=fis.read(fileBuffer))!=-1){
                    UDPReliableData frammento = new UDPReliableData(i,fileBuffer,cnt);
                   
                    byte[] datagramMessage = new byte[1024];
                    DatagramPacket datPacket = new DatagramPacket(datagramMessage,datagramMessage.length,packetIn.getAddress(),packetIn.getPort());
                    System.out.println("Invio pacchetto a "+ packetIn.getAddress() + " " + packetIn.getPort());
                    ByteArrayOutputStream bout = new ByteArrayOutputStream();
                    ObjectOutputStream dout = new ObjectOutputStream(bout);
                    
                    dout.writeObject(frammento);
                    String s = new String(frammento.getBuffer(),0,frammento.getCount());
                    //System.out.println("Frammento pronto per l'invio numero " + frammento.getSequenceNumber() + " : "+ s + " "+frammento.getCount());
                    dout.flush();
                    datagramMessage = bout.toByteArray();
                    datPacket.setData(datagramMessage);
                    datPacket.setLength(datagramMessage.length);
                    socketPop.send(datPacket);
                    bout.reset();
                    System.out.println("Pacchetto " + (i) + " trasmesso");
                    socketPop.setSoTimeout(30000);
                    try {
                        byte[] datagramAck = new byte[1024];
                    DatagramPacket ack = new DatagramPacket(datagramAck,datagramAck.length);
                    socketPop.receive(ack);
                    System.out.println("Ricevo ack da " + ack.getAddress() + " " + ack.getPort());
                    ByteArrayInputStream binput = new ByteArrayInputStream(ack.getData(),0,ack.getLength());
                    DataInputStream ddis = new DataInputStream(binput);
                    int ackNum = ddis.readInt();
                    if (ackNum != (i))
                        i=i-1;

                    System.out.println("Ricevuto ack" + ackNum);
                    }
                    catch(SocketException ex)
                    {
                        i=i-1;
                    }
                    catch(Exception fex)
                    {
                        System.out.println("Eccezione dell'ack " + fex.getMessage());
                    }

                    i++;
                }

                System.out.println("File frammentato");
                
                String[] addrIP = "127.0.0.1".split("\\.");
                
                byte[] byteIP = new byte[addrIP.length];
                for(int p = 0;p<addrIP.length;p++)
                   byteIP[p] = Byte.decode(addrIP[p]);

                System.out.println("ho inviato il file");
                byte[] datagramMessage = new byte[1024];
                DatagramPacket datPacket = new DatagramPacket(datagramMessage,datagramMessage.length,packetIn.getAddress(),packetIn.getPort());
                ByteArrayOutputStream bout = new ByteArrayOutputStream();
                ObjectOutputStream dout = new ObjectOutputStream(bout);
                dout.writeObject(new UDPReliableData(-1,new byte[512],0));
                dout.flush();
                datagramMessage = bout.toByteArray();
                datPacket.setData(datagramMessage);
                datPacket.setLength(datagramMessage.length);
                socketPop.send(datPacket);
                bout.reset();
                System.out.println("Invio fine file");

        }
        catch(Exception e)
        {
            e.printStackTrace();
            System.out.println("Eccezione managerThreadPOP: " + e.getLocalizedMessage());
        }
    }
}